package com.axsoft.jobimp.tests;

import junit.framework.TestCase;

import com.axsoft.jobimp.types.BLK;
import com.axsoft.jobimp.types.Bool;
import com.axsoft.jobimp.types.DateTime;
import com.axsoft.jobimp.types.LongWord;
import com.axsoft.jobimp.types.QuadWord;
import com.axsoft.jobimp.types.UTF8;
import com.axsoft.jobimp.types.Word;

public class TypesTest extends TestCase {
	
	public void testWord() {
		Word word = new Word(Short.MAX_VALUE);
		final byte[] bytes = {0x7F, (byte)0xFF};
		assertTrue(OTestUtils.byteArraysEquals(bytes, word.getData()));
		
		// Now test for byte array parsing
		word = new Word(bytes);
		assertEquals(0x7FFF, word.getValue());
	}
	
	public void testLongWord() {
		LongWord longWord = new LongWord();
		longWord.setLongWord(Integer.MAX_VALUE);
		
		final byte[] bytes = {0x7F, (byte)0xFF, (byte)0xFF, (byte)0xFF};
		
		assertTrue(OTestUtils.byteArraysEquals(bytes, longWord.getData()));
		
		// Test byte array parsing
		longWord = new LongWord(bytes);
		assertEquals(Integer.MAX_VALUE, longWord.getValue());
	}
	
	public void testQuadWord() {
		QuadWord quadWord = new QuadWord();
		quadWord.setQuadWord((long) Long.MAX_VALUE);
		
		final byte[] bytes = {0x7F, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
				(byte)0xFF };
		
		assertTrue(OTestUtils.byteArraysEquals(bytes, quadWord.getData()));
		
		// Test byte array parsing
		quadWord = new QuadWord(bytes);
		assertEquals((long) Long.MAX_VALUE, quadWord.getValue());
	}
	
	public void testDateTime() {
		DateTime dateTime = new DateTime((long) Long.MAX_VALUE);
		
		final byte[] bytes = {0x7F, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
				(byte)0xFF };
		
		assertTrue(OTestUtils.byteArraysEquals(bytes, dateTime.getData()));
		
		// Test byte array parsing
		dateTime = new DateTime(bytes);
		assertEquals((long) Long.MAX_VALUE, dateTime.getTimeInMillis());
	}
	
	public void testBLK() {
		final BLK blk = new BLK();
		final byte[] firstBytes = {0x00, 0x01, 0x02};
		final byte[] middleBytes = {0x03, 0x04, 0x05};
		final byte[] lastBytes = {0x06, 0x07, 0x08};
		
		blk.setBLK(firstBytes);
		blk.addBytes(middleBytes);
		blk.addBLK(new BLK(lastBytes));
		
		assertEquals(firstBytes.length + middleBytes.length + lastBytes.length, blk.getLength());
		
		for (byte i = 0x00; i < 0x09; i++) {
			assertEquals(i, blk.getByte(i));
		}
	}
	
	public void testBLKCopyBytes() {
		// I'm sure, that we need to test only 2 types
		final BLK blk = new BLK();
		final byte[] constFirst = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
		final byte[] constWord = {0x06, 0x07};
		final byte[] constLongWord = {0x0C, 0x0D, 0x0E, 0x0F};	
		
		blk.addBytes(constFirst);
		blk.addBytes(constWord);
		blk.addBytes(constLongWord);
		
		final byte[] first = blk.copyBytes(0, 6).getData();
		final byte[] word = blk.getWord(6).getData();
		final byte[] longWord = blk.getLongWord(8).getData();
		
		assertTrue(OTestUtils.byteArraysEquals(constFirst, first));
		assertTrue(OTestUtils.byteArraysEquals(constWord, word));
		assertTrue(OTestUtils.byteArraysEquals(constLongWord, longWord));
	}
	
	public void testUTF8() {
		final UTF8 utf8 = new UTF8();
		utf8.setUTF8("Hello, World!");
		final byte[] bytes = utf8.getData();
		utf8.setBytes(bytes);
		
		assertEquals("Hello, World!", utf8.getString());
	}
	
	public void testBool() {
		final Bool bool = new Bool();
		
		bool.setBool(true);
		assertTrue(bool.getValue());
		assertEquals((byte) 0xFF, bool.getByte(0)); 
		
		bool.setBool(false);
		assertFalse(bool.getValue());
		assertEquals((byte) 0x00, bool.getByte(0));
	}
	
}
